﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DHQGHN.DAL.Common;
using DHQGHN.DAL.DAO.Admin;
using DHQGHN.DAL.Models.Admin;
using System.Configuration;
using System.DirectoryServices.Protocols;
using System.Net;

namespace DHQGHN.DAL.BO.Admin
{
    public class UserBO : BaseBO
    {
        //Field Name in return DataSet
        public const string Field_ID = "Id";
        public const string Field_UserName = "Username";
        public const string Field_Password = "Password";
        public const string Field_FullName = "FullName";
        public const string Field_RegDate = "RegDate";
        public const string Field_Email = "Email";
        public const string Field_IsActive = "IsActive";
        public const string Field_Status = "Status";
        public const string Field_ADM_UNIT_ID = "ADM_UNIT_ID";
        public const string Field_DS_RecordCount = "RecordCount";
        public const string Field_DS_App_Id = "AppId";
        public const string Field_DS_Countday = "Countday";


        public string UserName { get; set; }

        public string Password { get; set; }

        public bool RememberMe { get; set; }

        private String _connectionString;

        public UserBO(string connString)
        {
            this._connectionString = connString;

        }
        public UserBO()
        {
            this._connectionString = Common.ConnectionUtil.DHQG_ADMIN_CONNECTION_STRING;

        }

        public UserDAO _userDAO;
        public RoleDAO _roleDAO;

        public UserDAO CreateSQLDAO()
        {
            return new UserDAO(_connectionString, DEFAULT_MAPPER_TYPE);
        }

        public bool CreateUser(UserModel user)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.CreateUser(user);
            }
            catch
            {
                throw;
            }
        }

        public bool RegisterUser(USER_GROUP_CREATE user)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.RegisterUser(user);
            }
            catch
            {
                throw;
            }
        }

        public bool ResetPassWordByforget(USER_GROUP_CREATE user)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.ResetPassWordByforget(user);
            }
            catch
            {
                throw;
            }
        }

        public bool UpdateUser(USER_GROUP_CREATE user)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.UpdateUser(user);
            }
            catch
            {
                throw;
            }
        }

        public bool UpdateUser_DHQG(USER_GROUP_CREATE user)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.UpdateUser_DHQG(user);
            }
            catch
            {
                throw;
            }
        }

        public bool actionCreateUserInGroupByListGroup(UserInListGroup ea)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.actionCreateUserInGroupByListGroup(ea);
            }
            catch
            {
                throw;
            }
        }

        public bool CheckUserExist(string userName, int appId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.CheckUserExist(userName, appId);
            }
            catch
            {
                throw;
            }
        }

        public bool ResetPassword(int userId, string PassWord)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.ResetPassword(userId, PassWord);
            }
            catch
            {
                throw;
            }
        }

        public bool CheckEmail(string Email, string AppCode)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.CheckEmail(Email, AppCode);
            }
            catch
            {
                throw;
            }
        }

        public bool Login(string userName, string password, string appCode)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_Password,Field_Password},  
                    {UserModel.Field_FullName,Field_FullName},                    
                    {UserModel.Field_Email,Field_Email},                   
                    {UserModel.Field_AppId, Field_DS_App_Id}
                };
                return _userDAO.Login(userName, password, appCode, mapDictionary);
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// Author: Huydq
        /// Check authentication base on LDAP
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool LDAPAuthentication(string username, string password)
        {
            bool isAuthenticated = false;
            string server = ConfigurationManager.AppSettings["LDAP_SERVER"];
            int portNumber = Convert.ToInt32(ConfigurationManager.AppSettings["LDAP_PORT_NUMBER"]);
            string baseDn = ConfigurationManager.AppSettings["LDAP_BASEDN"];
            try
            {
                LdapConnection ldap = new LdapConnection(new LdapDirectoryIdentifier(server, portNumber));
                ldap.AuthType = AuthType.Basic;
                SearchRequest request = new SearchRequest(baseDn, string.Format("uid={0}", username), System.DirectoryServices.Protocols.SearchScope.Subtree);
                SearchResponse response = (SearchResponse)ldap.SendRequest(request);
                if (1 == response.Entries.Count)
                {
                    ldap.Bind(new NetworkCredential(response.Entries[0].DistinguishedName, password));
                    isAuthenticated = true;
                }
                else
                {
                    isAuthenticated = false;
                }
                return isAuthenticated;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Author: Huydq
        /// Check username is existed on LDAP 
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static bool CheckLDAPUserExist(string userName)
        {
            string server = ConfigurationManager.AppSettings["LDAP_SERVER"];
            int portNumber = Convert.ToInt32(ConfigurationManager.AppSettings["LDAP_PORT_NUMBER"]);
            string baseDn = ConfigurationManager.AppSettings["LDAP_BASEDN"];
            try
            {
                LdapConnection ldap = new LdapConnection(new LdapDirectoryIdentifier(server, portNumber));
                ldap.AuthType = AuthType.Basic;
                SearchRequest request = new SearchRequest(baseDn, string.Format("uid={0}", userName), System.DirectoryServices.Protocols.SearchScope.Subtree);
                SearchResponse response = (SearchResponse)ldap.SendRequest(request);
                if (1 == response.Entries.Count)
                {
                    /*foreach (SearchResultEntry entry in response.Entries)
                    {//Muốn lấy tên thì làm thế này
                        if (entry.Attributes.Contains("cn") && entry.Attributes["cn"][0].ToString() != String.Empty)
                        {
                            // tên= entry.Attributes["cn"][0].ToString();
                        }

                    }*/
                    return true;
                }
                else
                    return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Checks if user with given password exists in the database
        /// </summary>
        /// <param name="_username">User name</param>
        /// <param name="_password">User password</param>
        /// <returns>True if user exist and password is correct</returns>
        public bool IsValid(string _username, string _password)
        {
            _userDAO = CreateSQLDAO();
            Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_Password,Field_Password},                    
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_RegDate,Field_RegDate},
                    {UserModel.Field_Email,Field_Email}, 
                    {UserModel.Field_IsActive,Field_IsActive},
                    {UserModel.Field_RecordCount,Field_DS_RecordCount}
                    
                };

            return _userDAO.checkValidUser(_username, _password, mapDictionary);
        }

        public DataPage<UserModel> GetDynamicListPaging(UserModel uModel, int pageSize, int pageIndex, bool compareEqual)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_Password,Field_Password},  
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_RegDate,Field_RegDate},
                    {UserModel.Field_Email,Field_Email},
                    {UserModel.Field_IsActive,Field_IsActive},
                    {UserModel.Field_ADM_UNIT_ID,Field_ADM_UNIT_ID},
                    {UserModel.Field_Status,Field_Status},
                    {UserModel.Field_AppId,Field_DS_App_Id},
                    {UserModel.Field_RecordCount,Field_DS_RecordCount}
                    
                };
                return _userDAO.GetDynamicListPaging(uModel, pageSize, pageIndex, mapDictionary, compareEqual);
            }
            catch (Exception)
            {
                throw;
            }
        }

        public DataPage<UserModel> GetDynamicListPagingd(UserModel uModel, int pageSize, int pageIndex, bool compareEqual)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_Password,Field_Password},  
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_RegDate,Field_RegDate},
                    {UserModel.Field_Email,Field_Email},
                    {UserModel.Field_IsActive,Field_IsActive},
                    {UserModel.Field_ADM_UNIT_ID,Field_ADM_UNIT_ID},
                    {UserModel.Field_RecordCount,Field_DS_RecordCount}
                    
                };
                return _userDAO.GetDynamicListPagingd(uModel, pageSize, pageIndex, mapDictionary, compareEqual);
            }
            catch (Exception)
            {
                throw;
            }
        }

        public UserModel GetUserByUserName(string userName)
        {
            _userDAO = CreateSQLDAO();
            Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_IsActive,Field_IsActive},
                    {UserModel.Field_ADM_UNIT_ID,Field_ADM_UNIT_ID},
                    {UserModel.Field_AppId,Field_DS_App_Id},
                    
                };

            return _userDAO.GetUserByUserName(userName, mapDictionary);
        }

        public UserModel GetUserInfo(string userName, string appCode)
        {
            _userDAO = CreateSQLDAO();
            Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_IsActive,Field_IsActive},
                    {UserModel.Field_ADM_UNIT_ID,Field_ADM_UNIT_ID},
                    {UserModel.Field_CountDay,Field_DS_Countday},
                    {"GroupCode" , "GroupCode"}
                };

            return _userDAO.GetUserInfo(userName, appCode, mapDictionary);
        }

        public string GetCodeGroupByUser(int userID)
        {
            _userDAO = CreateSQLDAO();
            return _userDAO.GetCodeGroupByUser(userID);
        }

        public bool deleteUser(int appId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.deleteUser(appId);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public bool deleteUser(string[] userName, string appCode)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.deleteUser(userName, appCode);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public bool deleteUserCheck(int[] appId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.deleteUserCheck(appId);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public bool Reactive(string userName, string appCode)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.Reactive(userName, appCode);
            }
            catch
            {

                throw;
            }
        }

        public bool reActiveUser(int appId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.reActiveUser(appId);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public List<UserModel> GetAll(int? AppId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_ADM_UNIT_ID,Field_ADM_UNIT_ID}                    
                };
                return _userDAO.GetAll(AppId, mapDictionary);
            }
            catch (Exception)
            {
                throw;
            }
        }

        public bool actionCreateOrAddUser(UserModel userModel)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.createOrUpdateGroup(userModel);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public bool isUnique(string _username)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.isUnique(_username);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public int GetIsActiveById(int? userId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.GetIsActiveById(userId);
            }
            catch (Exception e)
            {
                throw;
            }
        }

        public bool CheckActive(string _username)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.CheckActive(_username);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public UserModel GetUserById(int? userId)
        {
            _userDAO = CreateSQLDAO();
            Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_AppId,Field_DS_App_Id},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_IsActive,Field_IsActive},
                    {UserModel.Field_ADM_UNIT_ID,Field_ADM_UNIT_ID},
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_Email,Field_Email}
                };

            return _userDAO.GetUserById(userId, mapDictionary);
        }

        public List<UserModel> GetAllUserByGroupId(int groupId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                     {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_Password,Field_Password},  
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_RegDate,Field_RegDate},
                    {UserModel.Field_Email,Field_Email},
                    {UserModel.Field_IsActive,Field_IsActive},
                    {UserModel.Field_ADM_UNIT_ID,Field_ADM_UNIT_ID}                   
                };
                return _userDAO.GetAllUserByGroupId(groupId, mapDictionary);
            }
            catch (Exception)
            {
                throw;
            }
        }

        public List<UserModel> GetUserNameByUserId(int userId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                    {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},   
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_Email,Field_Email}
                };
                return _userDAO.GetUserNameByUserId(userId, mapDictionary);
            }
            catch (Exception)
            {
                throw;
            }
        }

        public string GetPasswordSalt(string userName, string appCode)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                return _userDAO.GetPasswordSalt(userName, appCode);
            }
            catch
            {

                throw;
            }
        }

        public List<UserModel> GetListUserToAsignInGroup(int groupId, int donViId)
        {
            try
            {
                _userDAO = CreateSQLDAO();
                Dictionary<String, String> mapDictionary = new Dictionary<string, string>()
                {
                     {UserModel.Field_ID,Field_ID},
                    {UserModel.Field_UserName,Field_UserName},
                    {UserModel.Field_FullName,Field_FullName},
                    {UserModel.Field_RegDate,Field_RegDate},
                    {UserModel.Field_Email,Field_Email},
                    {UserModel.Field_IsActive,Field_IsActive}                
                };
                return _userDAO.GetListUserToAsignInGroup(groupId, donViId, mapDictionary);
            }
            catch
            {

                throw;
            }
        }

    }
}

